package at.jku.novellbedsidedevice.service;

import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import at.jku.novellbedsidedevice.datasource.sleepquality.SensorData;
import at.jku.novellbedsidedevice.datasource.sleepquality.SleepQualityDatasource;

public class AccelerometerService extends Service implements SensorEventListener {

	// variables to store last sensor values
	private float[] oldValues;
	private float[] relValues;
	private boolean firstRun;

	private int sensorCnt;

	// variables for SensorEvents
	private SensorManager mSensorManager;
	private Sensor mAccelerometer;
	private long timeOffsetMs = System.currentTimeMillis() - System.nanoTime() / 1000000;

	@Override
	public void onCreate() {
		super.onCreate();
		mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		relValues = new float[3];
		oldValues = new float[3];
		firstRun = true;
		sensorCnt = 0;
	}

	/**
	 * Method to stop the Service
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		mSensorManager.unregisterListener(this);
		SleepQualityDatasource.getInstance().flushStoredSleepQualityObjects();
	}

	/**
	 * starts the Service and registers the Listener for the Accelerometer-Sensors
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
		return START_STICKY;
	}

	/**
	 * is called when a Sensor has got a new value
	 */
	public void onSensorChanged(SensorEvent event) {
		if (sensorCnt == 0) {
			long actualTimeMs = timeOffsetMs + event.timestamp / 1000000;

			// calculate relative changes of sensor data valus and create new sensordata object
			if (!firstRun) {
				// acceleration = lastValue - currentValue (changes over time)
				relValues[0] = Math.abs(oldValues[0] - event.values[0]);
				relValues[1] = Math.abs(oldValues[1] - event.values[1]);
				relValues[2] = Math.abs(oldValues[2] - event.values[2]);

				// System.out.println("old= "+oldValues[0]+" "+oldValues[1]+" "+oldValues[2]);
				// System.out.println("new= "+event.values[0]+" "+event.values[1]+" "+event.values[2]);
				// System.out.println("rel= "+relValues[0]+" "+relValues[1]+" "+relValues[2]);

				// add new sensor data to the datasouce
				SensorData sensorData = new SensorData(actualTimeMs, relValues.clone());
				SleepQualityDatasource.getInstance().addAccelerometerData(sensorData);
			} else {
				firstRun = false;
			}

			oldValues[0] = event.values[0];
			oldValues[1] = event.values[1];
			oldValues[2] = event.values[2];
		}

		sensorCnt--;
		if (sensorCnt < 0)
			sensorCnt = 10;
	}

	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// no action required
	}

	@Override
	public IBinder onBind(Intent intent) {
		// not used here
		return null;
	}
}
